#ifndef _NVIC_H_
#define _NVIC_H_

#include "soc.h"

typedef enum {
	/******  Cortex-M4 Processor Exceptions Numbers *************************************************************/
	NVIC_IRQ_NON_MASKABLE           = -14, /*!< 2 Non Maskable Interrupt                                        */
	NVIC_IRQ_MEMORY_MANAGEMENT      = -12, /*!< 4 Cortex-M4 Memory Management Interrupt                         */
	NVIC_IRQ_BUS_FAULT              = -11, /*!< 5 Cortex-M4 Bus Fault Interrupt                                 */
	NVIC_IRQ_USAGE_FAULT            = -10, /*!< 6 Cortex-M4 Usage Fault Interrupt                               */
	NVIC_IRQ_SV_CALL                = -5,  /*!< 11 Cortex-M4 SV Call Interrupt                                  */
	NVIC_IRQ_DEBUG_MONITOR          = -4,  /*!< 12 Cortex-M4 Debug Monitor Interrupt                            */
	NVIC_IRQ_PEND_SV                = -2,  /*!< 14 Cortex-M4 Pend SV Interrupt                                  */
	NVIC_IRQ_STK                    = -1,  /*!< 15 Cortex-M4 System Tick Interrupt                              */
	/******  STM32 specific Interrupt Numbers *******************************************************************/
	NVIC_IRQ_WWDG                   = 0,   /*!< Window WatchDog Interrupt                                       */
	NVIC_IRQ_PVD                    = 1,   /*!< PVD through EXTI Line detection Interrupt                       */
	NVIC_IRQ_TAMP_STAMP             = 2,   /*!< Tamper and TimeStamp interrupts through the EXTI line           */
	NVIC_IRQ_RTC_WKUP               = 3,   /*!< RTC Wakeup interrupt through the EXTI line                      */
	NVIC_IRQ_FLASH                  = 4,   /*!< FLASH global Interrupt                                          */
	NVIC_IRQ_RCC                    = 5,   /*!< RCC global Interrupt                                            */
	NVIC_IRQ_EXTI0                  = 6,   /*!< EXTI Line0 Interrupt                                            */
	NVIC_IRQ_EXTI1                  = 7,   /*!< EXTI Line1 Interrupt                                            */
	NVIC_IRQ_EXTI2                  = 8,   /*!< EXTI Line2 Interrupt                                            */
	NVIC_IRQ_EXTI3                  = 9,   /*!< EXTI Line3 Interrupt                                            */
	NVIC_IRQ_EXTI4                  = 10,  /*!< EXTI Line4 Interrupt                                            */
	NVIC_IRQ_DMA1_STREAM0           = 11,  /*!< DMA1 Stream 0 global Interrupt                                  */
	NVIC_IRQ_DMA1_STREAM1           = 12,  /*!< DMA1 Stream 1 global Interrupt                                  */
	NVIC_IRQ_DMA1_STREAM2           = 13,  /*!< DMA1 Stream 2 global Interrupt                                  */
	NVIC_IRQ_DMA1_STREAM3           = 14,  /*!< DMA1 Stream 3 global Interrupt                                  */
	NVIC_IRQ_DMA1_STREAM4           = 15,  /*!< DMA1 Stream 4 global Interrupt                                  */
	NVIC_IRQ_DMA1_STREAM5           = 16,  /*!< DMA1 Stream 5 global Interrupt                                  */
	NVIC_IRQ_DMA1_STREAM6           = 17,  /*!< DMA1 Stream 6 global Interrupt                                  */
	NVIC_IRQ_ADC                    = 18,  /*!< ADC1, ADC2 and ADC3 global Interrupts                           */
	NVIC_IRQ_CAN1_TX                = 19,  /*!< CAN1 TX Interrupt                                               */
	NVIC_IRQ_CAN1_RX0               = 20,  /*!< CAN1 RX0 Interrupt                                              */
	NVIC_IRQ_CAN1_RX1               = 21,  /*!< CAN1 RX1 Interrupt                                              */
	NVIC_IRQ_CAN1_SCE               = 22,  /*!< CAN1 SCE Interrupt                                              */
	NVIC_IRQ_EXTI9_5                = 23,  /*!< External Line[9:5] Interrupts                                   */
	NVIC_IRQ_TIM1_BRK_TIM9          = 24,  /*!< TIM1 Break interrupt and TIM9 global interrupt                  */
	NVIC_IRQ_TIM1_UP_TIM10          = 25,  /*!< TIM1 Update Interrupt and TIM10 global interrupt                */
	NVIC_IRQ_TIM1_TRG_COM_TIM11     = 26,  /*!< TIM1 Trigger and Commutation Interrupt and TIM11 global interrupt */
	NVIC_IRQ_TIM1_CC                = 27,  /*!< TIM1 Capture Compare Interrupt                                  */
	NVIC_IRQ_TIM2                   = 28,  /*!< TIM2 global Interrupt                                           */
	NVIC_IRQ_TIM3                   = 29,  /*!< TIM3 global Interrupt                                           */
	NVIC_IRQ_TIM4                   = 30,  /*!< TIM4 global Interrupt                                           */
	NVIC_IRQ_I2C1_EV                = 31,  /*!< I2C1 Event Interrupt                                            */
	NVIC_IRQ_I2C1_ER                = 32,  /*!< I2C1 Error Interrupt                                            */
	NVIC_IRQ_I2C2_EV                = 33,  /*!< I2C2 Event Interrupt                                            */
	NVIC_IRQ_I2C2_ER                = 34,  /*!< I2C2 Error Interrupt                                            */
	NVIC_IRQ_SPI1                   = 35,  /*!< SPI1 global Interrupt                                           */
	NVIC_IRQ_SPI2                   = 36,  /*!< SPI2 global Interrupt                                           */
	NVIC_IRQ_USART1                 = 37,  /*!< USART1 global Interrupt                                         */
	NVIC_IRQ_USART2                 = 38,  /*!< USART2 global Interrupt                                         */
	NVIC_IRQ_USART3                 = 39,  /*!< USART3 global Interrupt                                         */
	NVIC_IRQ_EXTI15_10              = 40,  /*!< External Line[15:10] Interrupts                                 */
	NVIC_IRQ_RTC_Alarm              = 41,  /*!< RTC Alarm (A and B) through EXTI Line Interrupt                 */
	NVIC_IRQ_OTG_FS_WKUP            = 42,  /*!< USB OTG FS Wakeup through EXTI line interrupt                   */
	NVIC_IRQ_TIM8_BRK_TIM12         = 43,  /*!< TIM8 Break Interrupt and TIM12 global interrupt                 */
	NVIC_IRQ_TIM8_UP_TIM13          = 44,  /*!< TIM8 Update Interrupt and TIM13 global interrupt                */
	NVIC_IRQ_TIM8_TRG_COM_TIM14     = 45,  /*!< TIM8 Trigger and Commutation Interrupt and TIM14 global interrupt */
	NVIC_IRQ_TIM8_CC                = 46,  /*!< TIM8 Capture Compare global interrupt                           */
	NVIC_IRQ_DMA1_STREAM7           = 47,  /*!< DMA1 Stream7 Interrupt                                          */
	NVIC_IRQ_FSMC                   = 48,  /*!< FSMC global Interrupt                                           */
	NVIC_IRQ_SDIO                   = 49,  /*!< SDIO global Interrupt                                           */
	NVIC_IRQ_TIM5                   = 50,  /*!< TIM5 global Interrupt                                           */
	NVIC_IRQ_SPI3                   = 51,  /*!< SPI3 global Interrupt                                           */
	NVIC_IRQ_UART4                  = 52,  /*!< UART4 global Interrupt                                          */
	NVIC_IRQ_UART5                  = 53,  /*!< UART5 global Interrupt                                          */
	NVIC_IRQ_TIM6_DAC               = 54,  /*!< TIM6 global and DAC1&2 underrun error  interrupts               */
	NVIC_IRQ_TIM7                   = 55,  /*!< TIM7 global interrupt                                           */
	NVIC_IRQ_DMA2_STREAM0           = 56,  /*!< DMA2 Stream 0 global Interrupt                                  */
	NVIC_IRQ_DMA2_STREAM1           = 57,  /*!< DMA2 Stream 1 global Interrupt                                  */
	NVIC_IRQ_DMA2_STREAM2           = 58,  /*!< DMA2 Stream 2 global Interrupt                                  */
	NVIC_IRQ_DMA2_STREAM3           = 59,  /*!< DMA2 Stream 3 global Interrupt                                  */
	NVIC_IRQ_DMA2_STREAM4           = 60,  /*!< DMA2 Stream 4 global Interrupt                                  */
	NVIC_IRQ_ETH                    = 61,  /*!< Ethernet global Interrupt                                       */
	NVIC_IRQ_ETH_WKUP               = 62,  /*!< Ethernet Wakeup through EXTI line Interrupt                     */
	NVIC_IRQ_CAN2_TX                = 63,  /*!< CAN2 TX Interrupt                                               */
	NVIC_IRQ_CAN2_RX0               = 64,  /*!< CAN2 RX0 Interrupt                                              */
	NVIC_IRQ_CAN2_RX1               = 65,  /*!< CAN2 RX1 Interrupt                                              */
	NVIC_IRQ_CAN2_SCE               = 66,  /*!< CAN2 SCE Interrupt                                              */
	NVIC_IRQ_OTG_FS                 = 67,  /*!< USB OTG FS global Interrupt                                     */
	NVIC_IRQ_DMA2_STREAM5           = 68,  /*!< DMA2 Stream 5 global interrupt                                  */
	NVIC_IRQ_DMA2_STREAM6           = 69,  /*!< DMA2 Stream 6 global interrupt                                  */
	NVIC_IRQ_DMA2_STREAM7           = 70,  /*!< DMA2 Stream 7 global interrupt                                  */
	NVIC_IRQ_USART6                 = 71,  /*!< USART6 global interrupt                                         */
	NVIC_IRQ_I2C3_EV                = 72,  /*!< I2C3 event interrupt                                            */
	NVIC_IRQ_I2C3_ER                = 73,  /*!< I2C3 error interrupt                                            */
	NVIC_IRQ_OTG_HS_EP1_OUT         = 74,  /*!< USB OTG HS End Point 1 Out global interrupt                     */
	NVIC_IRQ_OTG_HS_EP1_IN          = 75,  /*!< USB OTG HS End Point 1 In global interrupt                      */
	NVIC_IRQ_OTG_HS_WKUP            = 76,  /*!< USB OTG HS Wakeup through EXTI interrupt                        */
	NVIC_IRQ_OTG_HS                 = 77,  /*!< USB OTG HS global interrupt                                     */
	NVIC_IRQ_DCMI                   = 78,  /*!< DCMI global interrupt                                           */
	NVIC_IRQ_HASH_RNG               = 80,  /*!< RNG global Interrupt                                            */
	NVIC_IRQ_FPU                    = 81   /*!< FPU global interrupt                                            */
} NVIC_IrqEnum;

typedef enum {
	NVIC_GROUP_16 = 3,
	NVIC_GROUP_8  = 4,
	NVIC_GROUP_4  = 5,
	NVIC_GROUP_2  = 6,
	NVIC_GROUP_1  = 7,
} NVIC_GroupEnum;

/* 采用16个抢占优先级，无响应优先级 */
#define NVIC_GLOBAL_GROUP  3  //NVIC_GROUP_16

typedef enum {
#if NVIC_GLOBAL_GROUP == 7
	NVIC_PRIORITY_NONE = 0,
#endif
#if NVIC_GLOBAL_GROUP < 7
	NVIC_PRIORITY_HIGH = 0,
	NVIC_PRIORITY_0    = 0,
	NVIC_PRIORITY_1    = 1,
#endif
#if NVIC_GLOBAL_GROUP < 6
	NVIC_PRIORITY_2    = 2,
	NVIC_PRIORITY_3    = 3,
#endif
#if NVIC_GLOBAL_GROUP < 5
	NVIC_PRIORITY_4    = 4,
	NVIC_PRIORITY_5    = 5,
	NVIC_PRIORITY_6    = 6,
	NVIC_PRIORITY_7    = 7,
#endif
#if NVIC_GLOBAL_GROUP < 4
	NVIC_PRIORITY_8    = 8,
	NVIC_PRIORITY_9    = 9,
	NVIC_PRIORITY_10   = 10,
	NVIC_PRIORITY_11   = 11,
	NVIC_PRIORITY_12   = 12,
	NVIC_PRIORITY_13   = 13,
	NVIC_PRIORITY_14   = 14,
	NVIC_PRIORITY_15   = 15,
#endif
#if NVIC_GLOBAL_GROUP != 7
	NVIC_PRIORITY_LOW,
#endif
} NVIC_PriorityEnum;

typedef enum {
#if NVIC_GLOBAL_GROUP == 3
	NVIC_PRIORITY_SUB_NONE = 0,
#endif
#if NVIC_GLOBAL_GROUP > 3
	NVIC_PRIORITY_SUB_HIGH = 0,
	NVIC_PRIORITY_SUB_0    = 0,
	NVIC_PRIORITY_SUB_1    = 1,
#endif
#if NVIC_GLOBAL_GROUP > 4
	NVIC_PRIORITY_SUB_2    = 2,
	NVIC_PRIORITY_SUB_3    = 3,
#endif
#if NVIC_GLOBAL_GROUP > 5
	NVIC_PRIORITY_SUB_4    = 4,
	NVIC_PRIORITY_SUB_5    = 5,
	NVIC_PRIORITY_SUB_6    = 6,
	NVIC_PRIORITY_SUB_7    = 7,
#endif
#if NVIC_GLOBAL_GROUP > 6
	NVIC_PRIORITY_SUB_8    = 8,
	NVIC_PRIORITY_SUB_9    = 9,
	NVIC_PRIORITY_SUB_10   = 10,
	NVIC_PRIORITY_SUB_11   = 11,
	NVIC_PRIORITY_SUB_12   = 12,
	NVIC_PRIORITY_SUB_13   = 13,
	NVIC_PRIORITY_SUB_14   = 14,
	NVIC_PRIORITY_SUB_15   = 15,
#endif
#if NVIC_GLOBAL_GROUP != 3
	NVIC_PRIORITY_SUB_LOW,
#endif
} NVIC_PrioritySubEnum;

void NVIC_SetPriorityGroup(NVIC_GroupEnum group);
void NVIC_SetPriority(NVIC_IrqEnum irq, NVIC_PriorityEnum priority, NVIC_PrioritySubEnum sub);
void NVIC_EnableIrq(NVIC_IrqEnum irq);
void NVIC_DisableIrq(NVIC_IrqEnum irq);
void NVIC_SetPendIrq(NVIC_IrqEnum irq);
void NVIC_ClearPendIrq(NVIC_IrqEnum irq);

#endif /* _NVIC_H_ */
